#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
民法典数据服务
集成优化的搜索功能
"""

from typing import Dict, List, Optional, Tuple, Any
from flask import current_app
from pymongo import TEXT
from pymongo.errors import PyMongoError
from app.database import get_db
import re
import jieba
from datetime import datetime

class CivilCodeService:
    """民法典数据服务类"""
    
    def __init__(self):
        self.db = get_db()
        self.collection = self.db.civil_code_articles if self.db else None
        self.favorites_collection = self.db.user_favorites if self.db else None
        self.history_collection = self.db.search_history if self.db else None
        if self.collection:
            self._ensure_indexes()

    def _ensure_indexes(self):
        """确保所有必要的索引存在"""
        try:
            # 全文搜索索引
            if "civil_code_text_search" not in self.collection.index_information():
                self.collection.create_index([
                    ("content", TEXT),
                    ("title", TEXT),
                    ("explanation", TEXT),
                    ("keywords", TEXT)
                ], name="civil_code_text_search", default_language='none',
                weights={'content': 10, 'title': 5, 'explanation': 3, 'keywords': 8})
                current_app.logger.info("创建全文搜索索引 civil_code_text_search")

            # 关键词数组索引
            if "keywords_array_index" not in self.collection.index_information():
                self.collection.create_index([("keywords", 1)], name="keywords_array_index")
                current_app.logger.info("创建关键词数组索引 keywords_array_index")

            # 条文号唯一索引
            if "article_number_unique" not in self.collection.index_information():
                self.collection.create_index([("article_number", 1)], unique=True, name="article_number_unique")
                current_app.logger.info("创建条文号唯一索引 article_number_unique")

            # 章节复合索引
            if "chapter_compound_index" not in self.collection.index_information():
                self.collection.create_index([
                    ("chapter_info.part", 1),
                    ("chapter_info.chapter_number", 1)
                ], name="chapter_compound_index")
                current_app.logger.info("创建章节复合索引 chapter_compound_index")

            current_app.logger.info("所有索引已确保存在")

        except PyMongoError as e:
            current_app.logger.error(f"创建索引失败: {e}")
    
    # ==================== 文章查询相关 ====================
    
    def get_article_by_number(self, article_number: str) -> Optional[Dict]:
        """根据条文号获取法条"""
        if not self.collection:
            return None
        
        try:
            article = self.collection.find_one({"article_number": article_number})
            
            if article:
                if '_id' in article:
                    article['_id'] = str(article['_id'])
                current_app.logger.info(f"查询法条成功: {article_number}")
                return article
            else:
                current_app.logger.warning(f"法条不存在: {article_number}")
                return None
                
        except Exception as e:
            current_app.logger.error(f"查询法条失败: {str(e)}")
            return None
    
    def get_articles_by_chapter(self, part: str, chapter_number: int = None, 
                               page: int = 1, per_page: int = 20) -> Dict:
        """按章节获取法条列表"""
        try:
            # 构建查询条件
            query_filter = {"chapter_info.part": part}
            if chapter_number is not None:
                query_filter["chapter_info.chapter_number"] = chapter_number
            
            # 计算分页
            skip = (page - 1) * per_page
            
            # 查询法条
            articles = self.articles_db.find(
                query_filter,
                {"_id": 0},
                sort=[("article_number", 1)],
                limit=per_page,
                skip=skip
            )
            
            # 统计总数
            total = self.articles_db.count_documents(query_filter)
            
            result = {
                'articles': articles,
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': total,
                    'pages': (total + per_page - 1) // per_page
                }
            }
            
            current_app.logger.info(f"章节查询成功: {part}, 章节{chapter_number}, 共{total}条")
            return result
            
        except Exception as e:
            current_app.logger.error(f"章节查询失败: {str(e)}")
            return {'articles': [], 'pagination': {'page': 1, 'per_page': per_page, 'total': 0, 'pages': 0}}
    
    def get_chapters_list(self) -> List[Dict]:
        """获取章节列表"""
        try:
            pipeline = [
                {
                    "$group": {
                        "_id": {
                            "part": "$chapter_info.part",
                            "chapter_number": "$chapter_info.chapter_number",
                            "chapter_title": "$chapter_info.chapter_title"
                        },
                        "count": {"$sum": 1}
                    }
                },
                {
                    "$sort": {
                        "_id.part": 1,
                        "_id.chapter_number": 1
                    }
                },
                {
                    "$project": {
                        "_id": 0,
                        "part": "$_id.part",
                        "chapter_number": "$_id.chapter_number", 
                        "chapter_title": "$_id.chapter_title",
                        "article_count": "$count"
                    }
                }
            ]
            
            chapters = self.articles_db.aggregate(pipeline)
            current_app.logger.info(f"获取章节列表成功: {len(chapters)}个章节")
            return chapters
            
        except Exception as e:
            current_app.logger.error(f"获取章节列表失败: {str(e)}")
            return []
    
    # ==================== 智能搜索相关 ====================
    
    def smart_search(self, query: str, page: int = 1, per_page: int = 20) -> Dict:
        """智能组合搜索 - 集成优化的搜索策略"""
        try:
            # 收集所有搜索结果
            all_results = {}
            
            # 1. 文本搜索结果（高权重）
            text_results = self._text_search(query, per_page * 2)
            for result in text_results:
                article_id = result['article_number']
                score = result.get('score', 0) * 3  # 文本搜索权重3倍
                if article_id not in all_results or all_results[article_id]['score'] < score:
                    all_results[article_id] = {
                        **result,
                        'score': score,
                        'search_type': 'text'
                    }
            
            # 2. 关键词搜索结果（中权重）
            keyword_results = self._keyword_search(query, per_page * 2)
            for result in keyword_results:
                article_id = result['article_number']
                score = 2.0  # 关键词搜索权重2倍
                if article_id not in all_results or all_results[article_id]['score'] < score:
                    all_results[article_id] = {
                        **result,
                        'score': score,
                        'search_type': 'keyword'
                    }
            
            # 3. 内容搜索结果（基础权重）
            content_results = self._content_search(query, per_page * 2)
            for result in content_results:
                article_id = result['article_number']
                score = 1.0  # 内容搜索基础权重
                if article_id not in all_results or all_results[article_id]['score'] < score:
                    all_results[article_id] = {
                        **result,
                        'score': score,
                        'search_type': 'content'
                    }
            
            # 按得分排序
            sorted_results = sorted(all_results.values(), key=lambda x: x['score'], reverse=True)
            
            # 分页处理
            total = len(sorted_results)
            start = (page - 1) * per_page
            end = start + per_page
            paginated_results = sorted_results[start:end]
            
            # 移除score和search_type字段（前端不需要）
            for result in paginated_results:
                result.pop('score', None)
                result.pop('search_type', None)
                result.pop('_id', None)  # 移除MongoDB的_id字段
            
            search_result = {
                'articles': paginated_results,
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': total,
                    'pages': (total + per_page - 1) // per_page
                },
                'search_info': {
                    'query': query,
                    'search_time': datetime.now().isoformat(),
                    'result_count': total
                }
            }
            
            current_app.logger.info(f"智能搜索成功: '{query}', 共{total}条结果")
            
            # 记录搜索历史
            self._record_search_history(query, total)
            
            return search_result
            
        except Exception as e:
            current_app.logger.error(f"智能搜索失败: {str(e)}")
            return {
                'articles': [],
                'pagination': {'page': 1, 'per_page': per_page, 'total': 0, 'pages': 0},
                'search_info': {'query': query, 'search_time': datetime.now().isoformat(), 'result_count': 0}
            }
    
    def _text_search(self, query: str, limit: int = 20) -> List[Dict]:
        """文本搜索策略"""
        try:
            # 将查询分割为单词
            words = query.split()
            search_query = " ".join(words)
            
            results = self.articles_db.text_search(search_query, limit)
            return results
        except:
            return []
    
    def _keyword_search(self, query: str, limit: int = 20) -> List[Dict]:
        """关键词搜索策略"""
        try:
            results = self.articles_db.find(
                {"keywords": {"$in": [query]}},
                {"_id": 0},
                limit=limit
            )
            return results
        except:
            return []
    
    def _content_search(self, query: str, limit: int = 20) -> List[Dict]:
        """内容搜索策略"""
        try:
            results = self.articles_db.find(
                {"content": {"$regex": query, "$options": "i"}},
                {"_id": 0},
                limit=limit
            )
            return results
        except:
            return []
    
    def get_search_suggestions(self, query: str, limit: int = 10) -> List[str]:
        """获取搜索建议"""
        try:
            # 基于关键词的搜索建议
            pipeline = [
                {"$match": {"keywords": {"$regex": f".*{query}.*", "$options": "i"}}},
                {"$unwind": "$keywords"},
                {"$match": {"keywords": {"$regex": f".*{query}.*", "$options": "i"}}},
                {"$group": {"_id": "$keywords", "count": {"$sum": 1}}},
                {"$sort": {"count": -1}},
                {"$limit": limit},
                {"$project": {"_id": 1}}
            ]
            
            suggestions = self.articles_db.aggregate(pipeline)
            suggestion_list = [item['_id'] for item in suggestions]
            
            current_app.logger.info(f"搜索建议获取成功: '{query}', {len(suggestion_list)}条建议")
            return suggestion_list
            
        except Exception as e:
            current_app.logger.error(f"获取搜索建议失败: {str(e)}")
            return []
    
    # ==================== 收藏功能相关 ====================
    
    def add_favorite(self, user_id: str, article_number: str) -> bool:
        """添加收藏"""
        try:
            # 检查法条是否存在
            article = self.get_article_by_number(article_number)
            if not article:
                return False
            
            # 检查是否已收藏
            existing = self.favorites_db.find_one({
                "user_id": user_id,
                "article_number": article_number
            })
            
            if existing:
                return True  # 已收藏
            
            # 添加收藏
            favorite_doc = {
                "user_id": user_id,
                "article_number": article_number,
                "article_title": article.get('title', ''),
                "created_at": datetime.now().isoformat()
            }
            
            result = self.favorites_db.insert_one(favorite_doc)
            success = result is not None
            
            if success:
                current_app.logger.info(f"添加收藏成功: 用户{user_id}, 法条{article_number}")
            
            return success
            
        except Exception as e:
            current_app.logger.error(f"添加收藏失败: {str(e)}")
            return False
    
    def remove_favorite(self, user_id: str, article_number: str) -> bool:
        """移除收藏"""
        try:
            result = self.favorites_db.delete_one({
                "user_id": user_id,
                "article_number": article_number
            })
            
            success = result
            if success:
                current_app.logger.info(f"移除收藏成功: 用户{user_id}, 法条{article_number}")
            
            return success
            
        except Exception as e:
            current_app.logger.error(f"移除收藏失败: {str(e)}")
            return False
    
    def get_user_favorites(self, user_id: str, page: int = 1, per_page: int = 20) -> Dict:
        """获取用户收藏列表"""
        try:
            # 分页查询收藏
            skip = (page - 1) * per_page
            favorites = self.favorites_db.find(
                {"user_id": user_id},
                {"_id": 0},
                sort=[("created_at", -1)],
                limit=per_page,
                skip=skip
            )
            
            # 统计总数
            total = self.favorites_db.count_documents({"user_id": user_id})
            
            result = {
                'favorites': favorites,
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': total,
                    'pages': (total + per_page - 1) // per_page
                }
            }
            
            current_app.logger.info(f"获取收藏列表成功: 用户{user_id}, 共{total}条")
            return result
            
        except Exception as e:
            current_app.logger.error(f"获取收藏列表失败: {str(e)}")
            return {'favorites': [], 'pagination': {'page': 1, 'per_page': per_page, 'total': 0, 'pages': 0}}
    
    # ==================== 搜索历史相关 ====================
    
    def _record_search_history(self, query: str, result_count: int, user_id: str = "anonymous"):
        """记录搜索历史"""
        try:
            history_doc = {
                "user_id": user_id,
                "query": query,
                "result_count": result_count,
                "created_at": datetime.now().isoformat()
            }
            
            self.history_db.insert_one(history_doc)
            
        except Exception as e:
            current_app.logger.error(f"记录搜索历史失败: {str(e)}")
    
    def get_search_history(self, user_id: str = "anonymous", limit: int = 20) -> List[Dict]:
        """获取搜索历史"""
        try:
            history = self.history_db.find(
                {"user_id": user_id},
                {"_id": 0},
                sort=[("created_at", -1)],
                limit=limit
            )
            
            current_app.logger.info(f"获取搜索历史成功: 用户{user_id}, {len(history)}条记录")
            return history
            
        except Exception as e:
            current_app.logger.error(f"获取搜索历史失败: {str(e)}")
            return []
    
    def clear_search_history(self, user_id: str = "anonymous") -> bool:
        """清空搜索历史"""
        try:
            # 删除指定用户的搜索历史
            result = self.history_db.collection.delete_many({"user_id": user_id})
            
            current_app.logger.info(f"清空搜索历史成功: 用户{user_id}, 删除{result.deleted_count}条记录")
            return True
            
        except Exception as e:
            current_app.logger.error(f"清空搜索历史失败: {str(e)}")
            return False
    
    # ==================== 统计信息相关 ====================
    
    def get_statistics(self) -> Dict:
        """获取系统统计信息"""
        try:
            stats = {
                'total_articles': self.articles_db.count_documents({}),
                'total_favorites': self.favorites_db.count_documents({}),
                'total_searches': self.history_db.count_documents({}),
                'last_updated': datetime.now().isoformat()
            }
            
            # 按编统计
            pipeline = [
                {"$group": {"_id": "$chapter_info.part", "count": {"$sum": 1}}},
                {"$sort": {"_id": 1}}
            ]
            
            part_stats = self.articles_db.aggregate(pipeline)
            stats['articles_by_part'] = {item['_id']: item['count'] for item in part_stats}
            
            current_app.logger.info("获取统计信息成功")
            return stats
            
        except Exception as e:
            current_app.logger.error(f"获取统计信息失败: {str(e)}")
            return {}

# 创建全局服务实例
civil_code_service = CivilCodeService()
